package com.res.share.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.res.share.common.exception.BusinessException;
import com.res.share.common.utils.CategoryUtils;
import com.res.share.common.Constants;
import com.res.share.model.*;
import com.res.share.model.dto.ArticleModel;
import com.res.share.model.dto.ArticleResponse;
import com.res.share.service.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class IndexServiceImpl implements IndexService {

    @Autowired
    private IResDownService resDownService;

    @Autowired
    private IResArtService artService;

    @Autowired
    private IResHistoryService resHistoryService;

    @Autowired
    private ThreadPoolExecutor executor;

    @Autowired
    private IResUserService resUserService;

    @Autowired
    private CacheService cacheService;

    @Autowired
    private IResTagService resTagService;

    @Autowired
    private IResFollowService resFollowService;

    @Override
    public Map<String, Object> findWebIndexData(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> result = new HashMap<>();
        Integer userId = null;
        ResUser userDetails = resUserService.findCurrentUserDetails(request, response);
        if (userDetails != null) {
            userId = userDetails.getId();
        }
        //获取最新资源
        Integer finalUserId = userId;
        CompletableFuture<Void> newArticlesFuture = CompletableFuture.runAsync(() -> {
            List<ArticleModel> resNewArticleList = getResNewArticleList(finalUserId);
            result.put("resNewArticleList", resNewArticleList);
        }, executor);

        //获取分类资源
        CompletableFuture<Void> articleOtherFuture = CompletableFuture.runAsync(() -> {
            List<ArticleResponse> articleList = getArticleResponses(finalUserId);
            result.put("resFirstPageArticleList", articleList);
        }, executor);

        //查询文章
        CompletableFuture<Void> articleFuture = CompletableFuture.runAsync(() -> {
            List<ArticleModel> resArtList = findFirstArticleDatss(finalUserId);
            result.put("resArtList", resArtList);
        }, executor);
        CompletableFuture.allOf(articleFuture, articleOtherFuture, newArticlesFuture).join();
        return result;
    }


    /**
     * 获取最新资源
     *
     * @param finalUserId
     * @return
     */
    private List<ArticleModel> getResNewArticleList(Integer finalUserId) {
        List<ArticleModel> resNewArticleList = new ArrayList<>();
        Object commonCache = cacheService.getCommonCache(Constants.RES_NEW_ARTICLE_KEY);
        if (commonCache != null && StringUtils.isNotEmpty(commonCache.toString())) {
            resNewArticleList = JSON.parseArray(commonCache.toString(), ArticleModel.class);
        } else {
            resNewArticleList = artService.findArtsList(finalUserId, 1);

            if (!CollectionUtils.isEmpty(resNewArticleList)) {
                cacheService.setCommonCache(Constants.RES_NEW_ARTICLE_KEY, JSON.toJSONString(resNewArticleList));
            }
        }
        return resNewArticleList;
    }

    /**
     * 分类获取数据
     *
     * @param finalUserId
     * @return
     */
    private List<ArticleResponse> getArticleResponses(Integer finalUserId) {
        List<ArticleResponse> articleList = new ArrayList<>();
        Object commonCache = cacheService.getCommonCache(Constants.RES_ARTICLE_BASE_KEY);
        if (commonCache != null && StringUtils.isNotEmpty(commonCache.toString())) {
            articleList = JSON.parseArray(commonCache.toString(), ArticleResponse.class);
        } else {
            List<ResCategory> selectList = CategoryUtils.getValue(Constants.CATE_BASE_KEY);
            if (!CollectionUtils.isEmpty(selectList)) {
                List<ResCategory> pidList = selectList.stream().filter(resCategory -> resCategory.getPid() == 0 && resCategory.getId() != 0).distinct().collect(Collectors.toList());
                Map<Integer, List<ResCategory>> treeMap = selectList.stream().collect(Collectors.groupingBy(ResCategory::getPid));
                List<ArticleResponse> finalArticleList = articleList;
                pidList.stream().forEach(resCategory -> {
                    ArticleResponse articleResponse = new ArticleResponse();
                    articleResponse.setUrl(resCategory.getUrl());
                    articleResponse.setCategotyName(resCategory.getCategotyName());
                    List<ArticleModel> articleModelList = new ArrayList<>();
                    List<Integer> integerList = new ArrayList<>();
                    //子分类
                    List<ResCategory> resCategories = treeMap.get(resCategory.getId());
                    if (!CollectionUtils.isEmpty(resCategories)) {
                        integerList = resCategories.stream().map(resCategory1 -> resCategory1.getId()).distinct().collect(Collectors.toList());
                    }
                    integerList.add(resCategory.getId());
                    Page<ArticleModel> page = new Page<>(1, 8);
                    IPage<ArticleModel> userPage = artService.findHotArticleList(page, 1, finalUserId, 1, integerList);
                    if (!CollectionUtils.isEmpty(userPage.getRecords())) {
                        articleModelList.addAll(userPage.getRecords());
                    }
                    articleResponse.setArticleModelList(articleModelList);
                    finalArticleList.add(articleResponse);
                });
            }

            if (!CollectionUtils.isEmpty(articleList)) {
                cacheService.setCommonCache(Constants.RES_ARTICLE_BASE_KEY, JSON.toJSONString(articleList));
            }
        }
        return articleList;
    }

    /**
     * 查询文章
     *
     * @param finalUserId
     * @return
     */
    private List<ArticleModel> findFirstArticleDatss(Integer finalUserId) {
        List<ArticleModel> resArtList = new ArrayList<>();
        Object commonCache = cacheService.getCommonCache(Constants.HOT_ARTICLE_BASE_KEY);
        if (commonCache != null && StringUtils.isNotEmpty(commonCache.toString())) {
            resArtList = JSON.parseArray(commonCache.toString(), ArticleModel.class);
        } else {
            resArtList = artService.findArtsList(finalUserId, 2);
            if (!CollectionUtils.isEmpty(resArtList)) {
                cacheService.setCommonCache(Constants.HOT_ARTICLE_BASE_KEY, JSON.toJSONString(resArtList));
            }
        }
        return resArtList;
    }


    @Override
    public Map<String, Object> findHotArticleList(Integer userId, Integer type, Integer pageNum) {
        Map<String, Object> resultMap = new HashMap<>();
        Page<ArticleModel> page = new Page<>(pageNum, 16);
        IPage<ArticleModel> userPage = artService.findHotArticleList(page, type, userId, 2, null);
        resultMap.put("hotArticleS", userPage != null ? userPage.getRecords() : null);
        resultMap.put("hotArticleSTotal", userPage != null ? userPage.getTotal() : 0);
        resultMap.put("hotCurrentPage", pageNum);
        return resultMap;
    }

    @Override
    public Map<String, Object> findArticleByCateId(Integer userId, int type, String pidName, String name, Integer pageNum) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("catId", null);
        resultMap.put("cateChildrenList", null);
        resultMap.put("titleName", null);
        List<ResCategory> selectList = CategoryUtils.getValue(Constants.CATE_BASE_KEY);
        Map<String, ResCategory> stringResCategoryMap = selectList.stream().collect(Collectors.toMap(ResCategory::getCategoryPinYin, Function.identity()));
        Map<Integer, List<ResCategory>> treeMap = selectList.stream().collect(Collectors.groupingBy(ResCategory::getPid));
        ResCategory resCategory = stringResCategoryMap.get(pidName);
        Integer id = resCategory.getId();
        List<Integer> integerList = new ArrayList<>();
        List<ResCategory> resCategories = treeMap.get(id);
        //子类查询资源
        if (StringUtils.isNotEmpty(name)) {
            ResCategory resCategory1 = stringResCategoryMap.get(name);
            if (resCategory1 != null) {
                Integer childId = resCategory1.getId();
                resultMap.put("catId", childId);
                resultMap.put("titleName", resCategory1.getCategotyName());
                integerList.add(childId);
            }
        } else {
            resultMap.put("catId", id);
            resultMap.put("titleName", resCategory.getCategotyName());
            if (!CollectionUtils.isEmpty(resCategories)) {
                integerList = resCategories.stream().map(resCategory1 -> resCategory1.getId()).distinct().collect(Collectors.toList());
            }
            integerList.add(id);
        }
        resultMap.put("pid", id);
        Page<ArticleModel> page = new Page<>(pageNum, 16);
        IPage<ArticleModel> userPage = artService.findHotArticleList(page, type, userId, 1, integerList);
        resultMap.put("hotArticleS", userPage != null ? userPage.getRecords() : null);
        resultMap.put("hotArticleSTotal", userPage != null ? userPage.getTotal() : 0);
        resultMap.put("hotCurrentPage", pageNum);
        //子分类
        if (!CollectionUtils.isEmpty(resCategories)) {
            resCategories.stream().sorted(Comparator.comparing(ResCategory::getId));
            resultMap.put("cateChildrenList", resCategories);
        }
        return resultMap;
    }

    @Override
    public Map<String, Object> searchArticleList(Integer pageNum, Integer userId, String keywords) {
        Map<String, Object> resultMap = new HashMap<>();
        Page<ArticleModel> page = new Page<>(pageNum, 16);
        IPage<ArticleModel> userPage = artService.searchArticleList(page, userId, keywords);
        List<ArticleModel> records = userPage.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            records.stream().forEach(articleModel -> {
                String title = articleModel.getTitle();
                articleModel.setTitle(title);
                articleModel.setTitleHtml(title.replaceAll(keywords, "<font color='#FF0000'>" + keywords + "</font>"));
            });
        }
        resultMap.put("searchArticles", records);
        resultMap.put("searchArticleSTotal", userPage != null ? userPage.getTotal() : 0);
        resultMap.put("searchCurrentPage", pageNum);
        resultMap.put("keywords", keywords);
        return resultMap;
    }

    @Override
    public Map<String, Object> findArtDetail(Integer userId, Integer articleId) {
        Map<String, Object> resultMap = new HashMap<>();
        ArticleModel articleModel = artService.findArtDetail(userId, articleId, null, 0, null);
        resultMap.put("articleModel", articleModel);
        if (articleModel == null) {
            return resultMap;
        }
        //查询下载次数
        Integer resDownNums = resDownService.findResDownNums(articleId);
        resultMap.put("resDownNums", resDownNums == null ? 0 : resDownNums);
        //子分类
        Integer cId = articleModel.getCId();
        //父分类
        Integer pId = articleModel.getPId();
        //类型
        Integer artType = articleModel.getArtType();
        //是否免费
        Integer freeType = articleModel.getFreeType();
        Integer level = articleModel.getLevel();
        List<ResCategory> selectList = CategoryUtils.getValue(Constants.CATE_BASE_KEY);
        //细节
        Map<Integer, ResCategory> resCategoryMap = selectList.stream().collect(Collectors.toMap(ResCategory::getId, Function.identity()));
        //父类-子类集合
        Map<Integer, List<ResCategory>> treeMap = selectList.stream().collect(Collectors.groupingBy(ResCategory::getPid));
        //文章还是资源
        resultMap.put("artType", artType);
        //是否免费
        resultMap.put("freeType", freeType);
        List<Integer> cidList = new ArrayList<>();

        String oneUrl = null;
        String oneName = null;
        String twoUrl = null;
        String twoName = null;
        //子类
        if (level != 0) {
            ResCategory resCategory = resCategoryMap.get(cId);
            twoUrl = resCategory.getUrl();
            twoName = resCategory.getCategotyName();
            ResCategory pidResCategory = resCategoryMap.get(resCategory.getPid());
            oneUrl = pidResCategory.getUrl();
            oneName = pidResCategory.getCategotyName();
            List<ResCategory> resCategories = treeMap.get(pId);
            if (!CollectionUtils.isEmpty(resCategories)) {
                cidList = resCategories.stream().map(resCategory1 -> resCategory1.getId()).distinct().collect(Collectors.toList());
            }
            cidList.add(pId);
        } else {
            if (cId == 0) {
                oneUrl = "/web/hotmsg.html";
                oneName = "热点资讯";
            } else {
                ResCategory resCategory = resCategoryMap.get(cId);
                oneUrl = resCategory.getUrl();
                oneName = resCategory.getCategotyName();
                List<ResCategory> resCategories = treeMap.get(cId);
                if (!CollectionUtils.isEmpty(resCategories)) {
                    cidList = resCategories.stream().map(resCategory1 -> resCategory1.getId()).distinct().collect(Collectors.toList());
                }
            }

            cidList.add(cId);
        }
        resultMap.put("oneUrl", oneUrl);
        resultMap.put("oneName", oneName);
        resultMap.put("twoUrl", twoUrl);
        resultMap.put("twoName", twoName);
        resultMap.put("level", level);
        resultMap.put("recommendArticleList", null);
        resultMap.put("beforeArticleModel", null);
        resultMap.put("beforeArticleFlag", 0);
        resultMap.put("likeList", null);
        resultMap.put("afterArticleModel", null);
        resultMap.put("afterArticleFlag", 0);
        //相关推荐
        List<Integer> finalCidList = cidList;
        CompletableFuture<Void> recommendArticleList1 = CompletableFuture.runAsync(() -> {
            List<ArticleModel> recommendArticleList = artService.recommendArticleList(finalCidList, artType);
            resultMap.put("recommendArticleList", recommendArticleList);
        }, executor);
        //猜你喜欢
        CompletableFuture<Void> likeCompletableFuture = CompletableFuture.runAsync(() -> {
            List<ArticleModel> likeList = artService.findLikeArticleList();
            resultMap.put("likeList", likeList);
        }, executor);
        //上一篇
        CompletableFuture<Void> beforeArticleModel1 = CompletableFuture.runAsync(() -> {
            ArticleModel beforeArticleModel = artService.findArtDetail(userId, articleId, cId, 1, artType);
            if (beforeArticleModel == null) {
                beforeArticleModel = artService.findArtDetail(userId, articleId, pId, 1, artType);
            }
            if (beforeArticleModel != null) {
                resultMap.put("beforeArticleFlag", 1);
            }
            resultMap.put("beforeArticleModel", beforeArticleModel);
        }, executor);
        //下一篇
        CompletableFuture<Void> afterArticleModel1 = CompletableFuture.runAsync(() -> {
            ArticleModel afterArticleModel = artService.findArtDetail(userId, articleId, cId, 2, artType);
            if (afterArticleModel == null) {
                afterArticleModel = artService.findArtDetail(userId, articleId, pId, 2, artType);
            }
            if (afterArticleModel != null) {
                resultMap.put("afterArticleFlag", 1);
            }
            resultMap.put("afterArticleModel", afterArticleModel);
        }, executor);
        CompletableFuture.allOf(recommendArticleList1, likeCompletableFuture, beforeArticleModel1, afterArticleModel1).join();
        return resultMap;
    }

    @Override
    public void updateArticleLookSee(Integer articleId) {
        artService.updateArticleLookSee(articleId);
    }

    @Override
    public void saveArticleHistory(Integer articleId, Integer finalUserId) {
        resHistoryService.saveHistory(articleId, finalUserId);
    }

    @Override
    public Map<String, Object> findTagArticleList(Integer pageNum, Integer userId, String tagpinyin) {
        Map<String, Object> resultMap = new HashMap<>();
        ResTag resTag = resTagService.findArtTagDetail(tagpinyin);
        List<ArticleModel> records = null;
        long total = 0;
        if (resTag != null) {
            Page<ArticleModel> page = new Page<>(pageNum, 16);
            IPage<ArticleModel> userPage = artService.findTagArticleList(page, userId, resTag.getId());
            records = userPage.getRecords();
            total = userPage.getTotal();
        }
        resultMap.put("searchArticles", records);
        resultMap.put("searchArticleSTotal", total);
        resultMap.put("searchCurrentPage", pageNum);
        resultMap.put("keywords", resTag != null ? resTag.getTagName() : null);
        return resultMap;
    }

    @Override
    public Map<String, Object> findUserSHopResList(Integer userId, Integer beLongUserId, Integer pageNum) {
        //人气 访问人次
        ResUser resUser = resUserService.getById(beLongUserId);
        if(resUser==null){
            throw new BusinessException("不存在该店铺");
        }
        Integer moods = resUser.getMoods();
        if(moods==null){
            moods=0;
        }
        moods+=1;
        CompletableFuture.runAsync(new Runnable() {
            @Override
            public void run() {
                resUserService.updateUserMoodsById(beLongUserId);
            }
        },executor);
        //粉丝
        List<Long> fansList=resFollowService.findUserResFollowList(beLongUserId,1);
        Integer userBelogtoS=CollectionUtils.isEmpty(fansList)?0:fansList.size();
        //关注
        List<Long> followList=resFollowService.findUserResFollowList(beLongUserId,2);
        Integer userLooks=CollectionUtils.isEmpty(followList)?0:followList.size();
        String userName = resUser.getUserName();
        String userImg = resUser.getUserImg();
        Map<String, Object> resultMap = new HashMap<>();
        Page<ArticleModel> page = new Page<>(pageNum, 16);
        IPage<ArticleModel> userPage = artService.findUserSHopResList(page, userId, beLongUserId);
        List<ArticleModel>   records = userPage.getRecords();
        long total = userPage.getTotal();
        resultMap.put("shopUserName", userName);
        resultMap.put("shopUserImg", userImg);
        resultMap.put("beLongUserId", beLongUserId);
        if(userId!=null){
            resultMap.put("lookFlag", CollectionUtils.isEmpty(fansList)?0:(fansList.contains(Long.valueOf(userId))?1:0));
        }else {
            resultMap.put("lookFlag", 0);
        }
        resultMap.put("userMoods", moods);
        resultMap.put("userBelogtoS", userBelogtoS);
        resultMap.put("userLooks", userLooks);
        resultMap.put("userArticles", records);
        resultMap.put("userArticleSTotal", total);
        resultMap.put("userCurrentPage", pageNum);
        return resultMap;
    }

}
